let fs = require('fs');
let path = require('path');
let { parse, stringify } = require('svgson');
let svgPathBoundingBox = require('svg-path-bounding-box');

let getPathBounds = d => {
  try {
    let bounds = svgPathBoundingBox(d);
    if (bounds && typeof bounds === 'object') {
      return {
        x: bounds.minX || 0,
        y: bounds.minY || 0,
        width: (bounds.maxX || 0) - (bounds.minX || 0),
        height: (bounds.maxY || 0) - (bounds.minY || 0),
      };
    }
    console.error('⚠️ 无效的边界值:', bounds);
    return null;
  } catch (err) {
    console.error('⚠️ 无法解析 path:', err.message);
    return null;
  }
};

let updateViewBox = (svgJson, bounds) => {
  svgJson.attributes.viewBox = `${bounds.x} ${bounds.y} ${bounds.width} ${bounds.height}`;
  return svgJson;
};

let processSvgFile = async (filePath, savePath) => {
  let content = fs.readFileSync(filePath, 'utf8');
  let svgJson = await parse(content);
  let pathElements = svgJson.children.filter(el => el.name === 'path' && el.attributes.d);
  if (pathElements.length === 0) {
    console.warn(`⚠️ 未找到 <path>：${filePath}`);
    return false;
  }
  // 合并所有 path 的边界
  let totalBounds = null;
  for (let el of pathElements) {
    let b = getPathBounds(el.attributes.d);
    if (b) {
      if (!totalBounds) {
        totalBounds = { ...b };
      } else {
        totalBounds.x = Math.min(totalBounds.x, b.x);
        totalBounds.y = Math.min(totalBounds.y, b.y);
        totalBounds.width = Math.max(totalBounds.x + totalBounds.width, b.x + b.width) - totalBounds.x;
        totalBounds.height = Math.max(totalBounds.y + totalBounds.height, b.y + b.height) - totalBounds.y;
      }
    }
  }
  if (totalBounds) {
    let fileName = path.basename(filePath);
    let saveFile = path.join(savePath, fileName);
    updateViewBox(svgJson, totalBounds);
    let output = stringify(svgJson);
    fs.writeFileSync(saveFile, output, 'utf8');
    console.log(`✅ 已裁剪: ${fileName}`);
    return true;
  }
  return false;
};

processSvgFile(
  `D:\\NodeTest\\DEMO\\25.svg`,
  `D:\\NodeTest\\DEMO`
);
